<?php


namespace app\system\service;

class ApiService
{
	public static function getlist($options)
	{
		$where = [];
		if (isset($options["id"]) && $options["id"] != "") {
			$where[] = ["id", "=", $options["id"]];
		}
		if (isset($options["type"]) && $options["type"] != "") {
			$where[] = ["type", "=", $options["type"]];
		}
		if (isset($options["name"]) && $options["name"] != "") {
			$where[] = ["", "exp", \think\Db::raw("`name` like '%{$options["name"]}%'")];
		}
		if (isset($options["keyword"]) && $options["keyword"] != "") {
			$where[] = ["", "exp", \think\Db::raw("`name` like '%{$options["keyword"]}%' or `describe` like  '%{$options["keyword"]}%' or `param` like '%{$options["keyword"]}%'")];
		}
		$list = \think\Db::name("app_api")->where($where)->order(["id" => "asc"])->page($options["page"], $options["limit"])->select();
		$count = \think\Db::name("app_api")->where($where)->count();
		$pages = ceil($count / $options["limit"]);
		$data = [];
		foreach ($list as $item) {
			$data[] = self::get_array_info($item);
		}
		self::update_app_api_config_route_cache();
		return ["code" => \app\system\model\Code::success, "data" => $data, "count" => $count, "pages" => $pages];
	}
	public static function get_array_info($item)
	{
		$data = $item;
		$data["address"] = getsiteurl() . "/api/" . $item["api"];
		$data["param"] = json_decode($data["param"], true);
		return $data;
	}
	public static function getinfo($options)
	{
		$item = \think\Db::name("app_api")->where(["id" => $options["id"]])->find();
		if (empty($item)) {
			return ["code" => \app\system\model\Code::fail, "msg" => "id不存在"];
		}
		return ["code" => \app\system\model\Code::success, "data" => self::get_array_info($item)];
	}
	public static function add($options)
	{
		\think\Db::startTrans();
		try {
			\think\Db::name("app_api")->insert(["name" => $options["name"], "type" => $options["type"], "verify_user" => $options["verify_user"], "controller" => $options["controller"], "method" => $options["method"], "describe" => $options["describe"], "param" => json_encode(empty($options["param"]) ? [] : $options["param"], JSON_FORCE_OBJECT), "api" => $options["api"], "addtime" => time()]);
			\think\Db::commit();
			return ["code" => \app\system\model\Code::success];
		} catch (\Exception $e) {
			\think\Db::rollback();
			return ["code" => \app\system\model\Code::error, "msg" => $e->getMessage()];
		}
	}
	public static function edit($options)
	{
		\think\Db::startTrans();
		try {
			$row = \think\Db::name("app_api")->where(["id" => $options["id"]])->find();
			if (empty($row)) {
				return ["code" => \app\system\model\Code::fail, "msg" => "id不存在"];
			}
			$data = ["name" => $options["name"], "type" => $options["type"], "verify_user" => $options["verify_user"], "controller" => $options["controller"], "method" => $options["method"], "describe" => $options["describe"], "param" => json_encode(empty($options["param"]) ? [] : $options["param"], JSON_UNESCAPED_UNICODE), "api" => $options["api"]];
			\think\Db::name("app_api")->where(["id" => $options["id"]])->update($data);
			\think\Db::commit();
			return ["code" => \app\system\model\Code::success];
		} catch (\Exception $e) {
			\think\Db::rollback();
			return ["code" => \app\system\model\Code::error, "msg" => $e->getMessage()];
		}
	}
	public static function del($options)
	{
		return ["code" => \app\system\model\Code::fail, "msg" => "暂不支持"];
		\think\Db::startTrans();
		try {
			$new = \think\Db::name("app_api")->where(["id" => $options["id"]])->find();
			if (empty($new)) {
				return ["code" => \app\system\model\Code::fail, "msg" => "id不存在"];
			}
			\think\Db::name("app_api")->where(["id" => $options["id"]])->delete();
			\think\Db::commit();
			return ["code" => \app\system\model\Code::success];
		} catch (\Exception $e) {
			\think\Db::rollback();
			return ["code" => \app\system\model\Code::error, "msg" => $e->getMessage()];
		}
	}
	public static function get_app_config($options)
	{
		$row = \think\Db::name("app_api")->where(["id" => $options["api_id"]])->find();
		if (empty($row)) {
			return ["code" => \app\system\model\Code::fail, "msg" => "api id不存在"];
		}
		$app = \think\Db::name("app")->where(["id" => $options["appid"]])->find();
		if (empty($app)) {
			return ["code" => \app\system\model\Code::fail, "msg" => "appid不存在"];
		}
		$params = json_decode($row["param"], true);
		$config = \think\Db::name("app_api_config")->where(["appid" => $options["appid"], "api_id" => $options["api_id"]])->find();
		$config["params"] = $config ? json_decode($config["params"], true) : [];
		$config["method"] = empty($config["method"]) ? "default" : $config["method"];
		$config["verify_user_token"] = empty($config["verify_user_token"]) ? 0 : $config["verify_user_token"];
		$config["verify_machine_code"] = empty($config["verify_machine_code"]) ? 0 : $config["verify_machine_code"];
		$config["verify_ip"] = empty($config["verify_ip"]) ? 0 : $config["verify_ip"];
		$config["extra_data"] = empty($config["extra_data"]) ? "" : $config["extra_data"];
		$config["extraDataEditConfig"] = isset($config["extraDataEditConfig"]) ? json_decode($config["extraDataEditConfig"], true) : [];
		$config["extraDataEditConfig"] = ["mode" => $config["extraDataEditConfig"]["mode"] ?? "default", "coder_language" => $config["extraDataEditConfig"]["coder_language"] ?? ""];
		$config["encryption_config"] = isset($config["encryption_config"]) ? json_decode($config["encryption_config"], true) : [];
		$config["encryption_config"] = ["param_name_transfer_encryption" => $config["encryption_config"]["param_name_transfer_encryption"] ?? -1, "param_value_transfer_encryption" => $config["encryption_config"]["param_value_transfer_encryption"] ?? -1, "api_transfer_signature_time_limit" => $config["encryption_config"]["api_transfer_signature_time_limit"] ?? -1, "api_transfer_signature_time_limit_maximum" => $config["encryption_config"]["api_transfer_signature_time_limit_maximum"] ?? 300, "api_transfer_signature_time_limit_minimum" => $config["encryption_config"]["api_transfer_signature_time_limit_minimum"] ?? 300, "api_response_encryption" => $config["encryption_config"]["api_response_encryption"] ?? -1, "api_data_transfer_verify_captcha" => $config["encryption_config"]["api_data_transfer_verify_captcha"] ?? -1, "api_transfer_signature_type" => $config["encryption_config"]["api_transfer_signature_type"] ?? -1, "api_response_signature_type" => $config["encryption_config"]["api_response_signature_type"] ?? -1, "api_response_data_format_type" => $config["encryption_config"]["api_response_data_format_type"] ?? -1, "api_response_signature_param_string_calculation_rule" => $config["encryption_config"]["api_response_signature_param_string_calculation_rule"] ?? -1, "api_data_transfer_encryption_type" => $config["encryption_config"]["api_data_transfer_encryption_type"] ?? -1, "api_data_transfer_encryption_encoded_type" => $config["encryption_config"]["api_data_transfer_encryption_encoded_type"] ?? -1, "json_unescaped_unicode" => $config["encryption_config"]["json_unescaped_unicode"] ?? -1, "api_request_verify_blacklist" => $config["encryption_config"]["api_request_verify_blacklist"] ?? -1, "api_request_forwarding_open" => $config["encryption_config"]["api_request_forwarding_open"] ?? -1, "api_request_forwarding_url" => $config["encryption_config"]["api_request_forwarding_url"] ?? "", "api_request_forwarding_response_data_takeover_open" => $config["encryption_config"]["api_request_forwarding_response_data_takeover_open"] ?? -1, "config" => ["aes" => ["key" => $config["encryption_config"]["config"]["aes"]["key"] ?? "", "iv" => $config["encryption_config"]["config"]["aes"]["iv"] ?? "", "mode" => $config["encryption_config"]["config"]["aes"]["mode"] ?? -1, "pkcs" => $config["encryption_config"]["config"]["aes"]["pkcs"] ?? -1], "rc4" => $config["encryption_config"]["config"]["rc4"] ?? ["key" => ""], "base64" => $config["config"]["base64"] ?? ["key" => ""], "des" => ["key" => $config["encryption_config"]["config"]["des"]["key"] ?? "", "mode" => $config["encryption_config"]["config"]["des"]["mode"] ?? -1, "pkcs" => $config["encryption_config"]["config"]["des"]["pkcs"] ?? -1], "rsa" => ["pkcs" => $config["encryption_config"]["config"]["rsa"]["pkcs"] ?? -1, "service_public_key" => $config["encryption_config"]["config"]["rsa"]["service_public_key"] ?? "", "service_private_key" => $config["encryption_config"]["config"]["rsa"]["service_private_key"] ?? "", "client_public_key" => $config["encryption_config"]["config"]["rsa"]["client_public_key"] ?? "", "client_private_key" => $config["encryption_config"]["config"]["rsa"]["client_private_key"] ?? ""], "custom" => ["encrypt_function" => $config["encryption_config"]["config"]["custom"]["encrypt_function"] ?? "", "decrypt_function" => $config["encryption_config"]["config"]["custom"]["decrypt_function"] ?? ""]]];
		$config["disable"] = !empty($config["disable"]) && $config["disable"];
		if ($app["type"] === 1) {
			$config["verify_user_token"] = 1;
		}
		foreach ($params as $param) {
			if (!isset($config["params"][$param["field"]])) {
				$config["params"][$param["field"]] = "";
			}
		}
		return ["code" => \app\system\model\Code::success, "data" => $config];
	}
	public static function set_app_config($options)
	{
		\think\Db::startTrans();
		try {
			$row = \think\Db::name("app_api")->where(["id" => $options["api_id"]])->find();
			if (empty($row)) {
				return ["code" => \app\system\model\Code::fail, "msg" => "api id不存在"];
			}
			$app = \think\Db::name("app")->where(["id" => $options["appid"]])->find();
			if (empty($app)) {
				return ["code" => \app\system\model\Code::fail, "msg" => "appid不存在"];
			}
			$config = \think\Db::name("app_api_config")->where(["appid" => $options["appid"], "api_id" => $options["api_id"]])->find();
			if (isset($options["encryption_config"]["reset_rsakey"]) && $options["encryption_config"]["reset_rsakey"]) {
				$rsa1 = \app\common\utils\Rsa::getNewKey($options["encryption_config"]["config"]["rsa"]["pkcs"] ?? 0);
				$rsa2 = \app\common\utils\Rsa::getNewKey($options["encryption_config"]["config"]["rsa"]["pkcs"] ?? 0);
				$options["encryption_config"]["config"]["rsa"] = ["pkcs" => $options["encryption_config"]["config"]["rsa"]["pkcs"] ?? 0, "service_public_key" => $rsa1["public_key"] ?? "", "service_private_key" => $rsa1["private_key"] ?? "", "client_public_key" => $rsa2["public_key"] ?? "", "client_private_key" => $rsa2["private_key"] ?? ""];
				unset($options["encryption_config"]["reset_rsakey"]);
			}
			$route = \think\Db::name("app_api_config")->where(["route" => $options["route"]])->find();
			if (empty($config)) {
				if ($options["route"] && !empty($route)) {
					return ["code" => \app\system\model\Code::fail, "msg" => "自定义接口路由地址不可用，该地址被占用(占用所在接口ID：{$route["api_id"]},所在应用ID：{$route["appid"]})"];
				}
				\think\Db::name("app_api_config")->insert(["appid" => $options["appid"], "route" => $options["route"] ?? "", "api_id" => $row["id"], "method" => $options["method"], "verify_user_token" => $options["verify_user_token"], "verify_machine_code" => $options["verify_machine_code"], "extra_data" => $options["extra_data"], "extraDataEditConfig" => json_encode($options["extraDataEditConfig"] ?? [], JSON_UNESCAPED_UNICODE), "params" => json_encode($options["params"] ?? [], JSON_UNESCAPED_UNICODE), "encryption_config" => json_encode($options["encryption_config"] ?? [], JSON_UNESCAPED_UNICODE), "disable" => $options["disable"], "verify_ip" => $options["verify_ip"]]);
			} else {
				if ($options["route"] && !empty($route) && $route["id"] != $config["id"]) {
					return ["code" => \app\system\model\Code::fail, "msg" => "自定义接口路由地址不可用，该地址被占用"];
				}
				\think\Db::name("app_api_config")->where("id", $config["id"])->update(["route" => $options["route"] ?? "", "api_id" => $row["id"], "method" => $options["method"] ?? "", "verify_user_token" => $options["verify_user_token"], "verify_machine_code" => $options["verify_machine_code"], "extra_data" => $options["extra_data"], "extraDataEditConfig" => json_encode($options["extraDataEditConfig"] ?? [], JSON_UNESCAPED_UNICODE), "params" => json_encode($options["params"] ?? [], JSON_UNESCAPED_UNICODE), "encryption_config" => json_encode($options["encryption_config"] ?? [], JSON_UNESCAPED_UNICODE), "disable" => $options["disable"], "verify_ip" => $options["verify_ip"]]);
			}
			\think\Db::commit();
			self::update_app_api_config_route_cache();
			return ["code" => \app\system\model\Code::success];
		} catch (\Exception $e) {
			\think\Db::rollback();
			return ["code" => \app\system\model\Code::error, "msg" => $e->getMessage()];
		}
	}
	public static function update_app_api_config_route_cache()
	{
		try {
			$apiConfigTable = \think\Db::name("app_api_config")->where("route", "<>", "")->select();
			$apiConfigIndex = [];
			foreach ($apiConfigTable as $index => $apiConfig) {
				$apiConfigIndex[$apiConfig["route"]] = $index;
			}
			\think\facade\Cache::set("app_api_config_table", json_encode($apiConfigTable));
			\think\facade\Cache::set("app_api_config_index", json_encode($apiConfigIndex));
			return ["code" => \app\system\model\Code::success];
		} catch (\Exception $e) {
			return ["code" => \app\system\model\Code::error, "msg" => $e->getMessage()];
		}
	}
}